package com.agile.leetcode.canculateObjectSize.lockstatus;

import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.TimeUnit;

/**
 * 锁膨胀升级的演示
 *
 * @Author:ChenZhangKun
 * @Date: 2021/7/27 15:18
 */
public class LockStatusChange {
    public static void main(String[] args) throws InterruptedException {
        User user_1 = new User();
        // 打印对象状态
        /**
         * 无状态（001）com.agile.leetcode.canculateObjectSize.lockstatus.User object internals:
         *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
         *       0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
         *       4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
         *       8     4        (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
         *      12     4    int User.id                                   0
         * Instance size: 16 bytes
         * Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
         * 此时是无锁状态 001 因为jvm默认开启偏向锁延迟4s,所以此时是无锁状态
         */
        System.out.println("无状态（001）" + ClassLayout.parseInstance(user_1).toPrintable());
        User user_2 = new User();
        // 休眠超过四秒钟
        TimeUnit.SECONDS.sleep(4);
        /**
         * 偏向锁101com.agile.leetcode.canculateObjectSize.lockstatus.User object internals:
         *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
         *       0     4        (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
         *       4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
         *       8     4        (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
         *      12     4    int User.id                                   0
         * Instance size: 16 bytes
         * Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
         * 此时是101处于偏向锁状态
         */
        System.out.println("偏向锁101" + ClassLayout.parseInstance(user_2).toPrintable());
        // 轻量级锁
        new Thread(() -> {
            /**
             * 轻量级锁(00)com.agile.leetcode.canculateObjectSize.lockstatus.User object internals:
             *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
             *       0     4        (object header)                           78 f0 8f 1a (01111000 11110000 10001111 00011010) (445640824)
             *       4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
             *       8     4        (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
             *      12     4    int User.id                                   0
             * Instance size: 16 bytes
             * Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
             * 此时是000
             */
            synchronized (user_1) {
                System.out.println("轻量级锁(00)" + ClassLayout.parseInstance(user_1).toPrintable());
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        // 重量级锁，具有锁冲突
        new Thread(() -> {
            /**
             * 重量级锁(10)com.agile.leetcode.canculateObjectSize.lockstatus.User object internals:
             *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
             *       0     4        (object header)                           7a 88 73 03 (01111010 10001000 01110011 00000011) (57903226)
             *       4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
             *       8     4        (object header)                           43 c1 00 20 (01000011 11000001 00000000 00100000) (536920387)
             *      12     4    int User.id                                   0
             * Instance size: 16 bytes
             * Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
             * 此时是010
             */
            synchronized (user_1) {
                System.out.println("重量级锁(10)" + ClassLayout.parseInstance(user_1).toPrintable());
            }
        }).start();
        System.out.println(user_1.hashCode());
    }
}
